/*
 * @Author       : Bing Chen chenbing@iocharger.com
 * @Date         : 2024-05-20 22:18:20
 * @LastEditors  : Bing Chen chenbing@iocharger.com
 * @LastEditTime : 2025-03-15 13:00:05
 * @FilePath     : \openchaoji-corelib\shared\include\OpenChaoJi_utility_transport.h
 * @Description  : 本文件定义通用的传输层数据通道建立, 监听, 连接, 断开, 发送数据, 接受数据, 销毁等通用操作, 实现对数据的封装收发
 *
 * Copyright (c) 2025 OpenChaoJi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the icense for the specific language governing permissions and
 * limitations under the License.
 *
 */

#ifndef OPENCHAOJI_TRANSPORT_H
#define OPENCHAOJI_TRANSPORT_H
#include "../include/OpenChaoJi_shared.h"
#include "OpenChaoJi_config.h"
#include "OpenChaoJi_type.h"


/**
 * 定义传输层消息发送结果状态
*/
enum OpenChaoJi_utility_transport_MsgSendResult {
	OPENCHAOJI_UTILITY_TRANSPORT_MSG_SEND_FAILED   = -1,		//发送失败
    OPENCHAOJI_UTILITY_TRANSPORT_MSG_SEND_IDLE      = 0,   		//初始化，复位
    OPENCHAOJI_UTILITY_TRANSPORT_MSG_SEND_ING    	= 1,   		//发送中
    OPENCHAOJI_UTILITY_TRANSPORT_MSG_SEND_FINISHED  = 2,   		//发送完成
    OPENCHAOJI_UTILITY_TRANSPORT_MSG_SEND_TIMEOUT_FAILED = 3, 	//发送总超时失败
    OPENCHAOJI_UTILITY_TRANSPORT_MSG_SEND_ERROR_FAILED   = 4,	//传输错误失败
    OPENCHAOJI_UTILITY_TRANSPORT_MSG_SEND_RECVNACK_FAILED = 5,  //接收到NACK失败
    OPENCHAOJI_UTILITY_TRANSPORT_MSG_SEND_ABORT_FAILED = 6,  	//主动中止失败
};

enum OpenChaoJi_transport_protocol_type {

    OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_UNKNOWN    = 0,
    OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_A = 1,
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
    OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_B = 2,
#endif
};


/**
 * @brief 本模块的上下文数据结构
 */
struct OpenChaoJi_context_utility_transport;


/**
 * @brief 创建本模块的上下文时需要传入的参数
 */
struct OpenChaoJi_create_info_utility_transport {

    int tag;

    int (* can_send_func)(void * param, const struct can_pdu * send_pdu);
    int (* can_recv_func)(void * param, struct can_pdu * recv_pdu);

    enum OpenChaoJi_transport_protocol_type transport_protocol_type;
	uint8_t src_addr;
	uint8_t dest_addr;

    void * param;
};

/**
 * @brief 初始化
 *
 * @param info 初始化信息
 * @return 成功返回创建的上下文指针，失败返回NULL。
 */
struct OpenChaoJi_context_utility_transport * OpenChaoJi_utility_transport_init(const struct OpenChaoJi_create_info_utility_transport * info);

/**
 * @brief 销毁
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 成功返回0，失败返回-1。
 */
int16_t OpenChaoJi_utility_transport_term(struct OpenChaoJi_context_utility_transport * context);

/**
 * @brief 复位, 清空收发缓冲区和队列
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 成功返回0，失败返回-1。
 */
int16_t OpenChaoJi_utility_transport_reset(struct OpenChaoJi_context_utility_transport * context);

/**
 * @brief 服务, 进行长消息或者需要应答消息的自动处理
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 成功返回0，失败返回-1。
 */
void OpenChaoJi_utility_transport_service(struct OpenChaoJi_context_utility_transport * context);

/**
 * @brief 发送一个完整数据包, 本模块需要自行判断是否是长消息, 如有需要本模块需要保存数据的副本
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @param send_data 待发送的数据结构
 * @return 读到数据返回0，读不到数据返回-1。
 */
int16_t OpenChaoJi_utility_transport_send(struct OpenChaoJi_context_utility_transport *context, struct OpenChaoJi_utility_data_buff_send_data * send_data);

/**
 * @brief 读取数据, 本模块会动态申请内存交给调用者, 调用者用完后记得释放内存, 防止内存泄漏
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @param recv_data 待读取数据结构, 注意读取方需要自行free接收的数据区
 * @return 读到数据返回0，读不到数据返回-1。
 */
int16_t OpenChaoJi_utility_transport_recv(struct OpenChaoJi_context_utility_transport *context, struct OpenChaoJi_utility_data_buff_recv_data * recv_data);

/**
 * @brief 获取不同消息数据包发送结果，调用数据包发送消息后，可通过本模块可查看发送状态结果，主要用于上层查询当前长消息或可靠消息的发送结果
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @param tag 消息类型
 * @return  -1: 发送失败   0: 初始化，复位   1: 发送中   2: 发送完成
 */
enum OpenChaoJi_utility_transport_MsgSendResult OpenChaoJi_utility_transport_get_sending_result(struct OpenChaoJi_context_utility_transport *context, enum OpenChaoJi_gbt27930_msg_type tag);

/**
 * @brief 传输层数据交互链接，对于GBT27930 的CAN传输，调用返回连接成功
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 连接成功返回0，失败返回-1。
 */
int16_t OpenChaoJi_utility_transport_connect(struct OpenChaoJi_context_utility_transport *context);

/**
 * @brief 传输层数据交互链接，对于GBT27930 的CAN传输，调用返回连接断开成功
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 连接断开成功返回0，连接断开失败返回-1。
 */
int16_t OpenChaoJi_utility_transport_disconnect(struct OpenChaoJi_context_utility_transport *context);

/**
 * @brief 传输层数据交互是否连接成功判断，对于GBT27930 的CAN传输，调用返回连接断开成功
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 0:未连接，1：已连接。
 */
int16_t OpenChaoJi_utility_transport_is_connected(struct OpenChaoJi_context_utility_transport *context);

/**
 * @brief 关闭传输层可靠消息的所有连接，可靠短消息发送，长消息接收和发送状态过程
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 连接成功返回0，失败返回-1。
 */
int16_t OpenChaoJi_utility_transport_close(struct OpenChaoJi_context_utility_transport *context);

/**
 * @brief OpenChaoJi的传输层设计和函数定义参考TCP/UDP的网络通讯思路，由于目前底层是CAN通信，对于listen，accept
 * 机制本版本暂不涉及，后续如果底层使用以太网通讯，后面版本可以实现对应函数。
 */

#endif // OPENCHAOJI_TRANSPORT_H.
